#ifndef __threadhpp__
#define __threadhpp__
#include <iostream>
#include <string>
#include <unistd.h>
#include <pthread.h>
#include <functional>
#include <string.h>
#include <stdlib.h>
using namespace std;
#endif
namespace ve
{
    static uint32_t num = 1;
    template<class t>
    class Thread
    {
        using func_t = function<void(t&)>;

    private:
        pthread_t _tid;
        string _name;
        bool _isdetached;
        bool _isrunning;
        void *_res;
        func_t _func;
        t _cnt;

    public:
        Thread(func_t func,t& cnt) : _tid(0),
                              _isdetached(false),
                              _isrunning(false),
                              _res(nullptr),
                              _func(func),
                              _cnt(cnt)
        {
            _name = "Thread-" + to_string(num++);
        }
        void detach()
        {
            if (_isrunning && _isdetached == false)
                pthread_detach(_tid);
            _isdetached = true;
        }
        static void *routine(void *args) // 为什么使用static：因为没有static的成员函数是默认带有this指针参数的，那么就会不符合pthread_created函数对routine函数参数的要求。但是如果使用了static修饰，那么就没有this指针参数，也就无法再调用成员变量_func函数，所以这里讲this指针传到了args中。
        {
            Thread<t> *self = static_cast<Thread<t>*>(args);
            self->_func(self->_cnt); // 回调函数_func
            return nullptr;
        }
        bool start()
        {
            if (_isrunning == false)
            {
                int n = pthread_create(&_tid, nullptr, routine, this);
                if (n != 0)
                {
                    cerr << "create thread error:" << strerror(n) << endl;
                    return false;
                }
                if (_isdetached)
                    pthread_detach(_tid);
                _isrunning = true;
                return true;
            }
            else
                return false;
        }
        bool stop()
        {
            if (_isrunning == false)
                return false;
            int n = pthread_cancel(_tid);
            if (n != 0)
            {
                cerr << "stop thread error: " << strerror(n) << endl;
                return false;
            }
            cout<<"线程： "<<_name<<" stop"<<endl;
            _isrunning = false;
            return true;
        }
        void join()
        {
            if (_isdetached)
                return;
            int n = pthread_join(_tid, &_res);
            if (n != 0)
                cerr << "join thread error: " << strerror(n) << endl;
            cout<<"线程： "<<_name<<" join"<<endl;
        }
        ~Thread()
        {
        }
    };
}